﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using AppEntity;

namespace AppEntity
{
    public partial class App
    {
        public class Record
        {
            internal XmlDocument AppDom;
            internal App App;
            internal Entity Entity;
            internal Common.DataBase.Sqlite Sqlite = null;
            internal XmlDocument EntityDom;

            private Dictionary<string, object> Data = new Dictionary<string, object>();

            /// <summary>
            /// 返回指定字段的值。当找不到 Column 列时，返回 null。
            /// </summary>
            /// <param name="Column"></param>
            /// <returns></returns>
            public object GetColumnValue(string Column)
            {
                if (this.Data.ContainsKey(Column))
                {
                    return this.Data[Column];
                }
                return null;
            }

            public void SetColumnValue(string Column, object Value)
            {
                Data[Column] = Value;                
            }

            /// <summary>
            /// 插入数据
            /// </summary>
            /// <param name="ReturnNewId"></param>
            /// <returns>返回-1表示插入数据库失败，返回0表示插入成功，无错误发生。当ReturnNewId==true时，返回最新插入数据的ID。</returns>
            public int Add(bool ReturnNewId)
            { 
                HashSet<string> Columns = (from n in this.Entity.Columns select n.Name).ToHashSet();
                foreach(string Key in this.Data.Keys)
                {
                    if (!Columns.Contains(Key))
                    {
                        Data.Remove(Key);
                    }                    
                }                
                string[] Cols = Data.Keys.ToArray();
                Common.DataBase.Sqlite.SqlteParam[] Params = new Common.DataBase.Sqlite.SqlteParam[Cols.Length];
                for (int i = 0; i < Cols.Length; i++)
                {
                    Params[i] = new Common.DataBase.Sqlite.SqlteParam() { Name=Cols[i], Value=this.Data[Cols[i]] };
                }
                int Result = this.Sqlite.ExecuteSql("INSERT INTO [Entity-" + this.Entity.ID + "-Data] (" + Cols.Join(",") + ") VALUES (@" + Cols.Join(",@") + ")", Params);
                if (Result>0 && ReturnNewId == true)
                {
                    return this.Sqlite.ExecuteScalar("select last_insert_rowid()").ToString().ToInt32(-1);
                    //return this.Sqlite.ExecuteScalar("SELECT id FROM [Entity-" + this.Entity.ID + "-Data] order by id desc limit 1").ToString().ToInt32(-1);
                }
                return Result==0 ? -1 : 0;
            }

            /// <summary>
            /// 必须通过 SetColumnValue() 方法传入有效的主键 id 值，否则将更新失败。
            /// </summary>
            /// <returns>仅当修改成功时，才返回 true。不包含id，或者id值无效、数据库中找不到id值时，都返回 false</returns>
            public bool Update()
            {
                if (!this.Data.ContainsKey("id")) return false;
                int id = this.Data["id"].ToString().ToInt32(0);
                if (id == 0) return false;

                HashSet<string> Columns = (from n in this.Entity.Columns select n.Name).ToHashSet();
                foreach (string Key in this.Data.Keys)
                {
                    if (!Columns.Contains(Key))
                    {
                        Data.Remove(Key);
                    }
                }
                string[] Cols = Data.Keys.ToArray();
                Common.DataBase.Sqlite.SqlteParam[] Params = new Common.DataBase.Sqlite.SqlteParam[Cols.Length];
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < Cols.Length; i++)
                {
                    Params[i] = new Common.DataBase.Sqlite.SqlteParam() { Name = Cols[i], Value = this.Data[Cols[i]] };
                    sb.Append(Cols[i] + "=@" + Cols[i] + ",");
                }
                string ColTxt = sb.ToString();
                ColTxt = ColTxt.Left(ColTxt.Length - 1);
                int Result = this.Sqlite.ExecuteSql("UPDATE [Entity-" + this.Entity.ID + "-Data] Set " + ColTxt + " WHERE id="+id, Params);                
                return Result > 0;
            }
        }

        
    }
}
